--[[数据示例
    {
        --基础设置
        name:必选，string，粒子特效的prefab名
        image：必选，string，粒子的贴图路径，注意需要加.tex文件后缀，且必须用resolvefilepath() 包装一下，否则会出现找不到贴图的错误，例如resolvefilepath("images/fx/heart.tex")
        needsharder：必选，string，粒子用到的sharder路径，例如"shaders/vfx_particle_reveal.ksh"
        InitEnvelope:可选，函数，颜色和缩放包络定义,包络(Envelope)本质上是一个时间-数值映射表，它定义了粒子属性如何随时间变化,举例如下：
                    local function InitEnvelope()
                        EnvelopeManager:AddColourEnvelope  --这个是颜色变化，定义粒子颜色随时间的变化
                        (
                            COLOUR_ENVELOPE_NAME,--这个是包络名，可以随便取，后续设置粒子颜色变化曲线是以该名为准
                            {--注意，过多的周期变化控制可以带来更优秀的视觉效果，但会增加计算资源
                                { 0,    IntColour(217, 39, 39, 160) },  --所有的表，第一项是粒子的生命周期，0-1，0是开始，1是结束，可以类比动画中的关键帧，第二项是颜色变对应rgba，最后一个a是透明度
                                { .19,  IntColour(217, 39, 39, 160) },
                                { .35,  IntColour(217, 39, 390, 80) },
                                { .51,  IntColour(217, 39, 39, 60) },
                                { .75,  IntColour(217, 39, 39, 40) },
                                { 1,    IntColour(217, 39, 39, 0) },
                            }
                        )


                         local glow_max_scale = .3
                        -- 添加位置变化，与上面颜色变化一样，猜测表中第一个元素是一个类似渐变或者时间的东西
                        -- 后面参数是缩放的大小了
                        EnvelopeManager:AddVector2Envelope
                        (
                            SCALE_ENVELOPE_NAME,--这个是包络名，可以随便取，建议是和颜色的包络名保持一致
                            {
                                { 0,    { glow_max_scale * 0.7, glow_max_scale * 0.7 } },--一样，前面是粒子对应的生命周期，后面则是粒子的缩放，其中第一个为x（宽度）缩放，第二个为y（高度）缩放
                                { .55,  { glow_max_scale * 1.2, glow_max_scale * 1.2 } },
                                { 1,    { glow_max_scale * 1.3, glow_max_scale * 1.3 } },
                            }
                        )
                        InitEnvelope = nil --使用过一次后清除，释放内存
                    end
        number:必选，数字,表示初始化的粒子发射器数量，一个粒子特效可以包含多个发射器，每个发射器负责生成不同类型或不同属性的粒子
        
        --渲染资源配置
        UVframesize:表，用于裁剪tex图片的终点，需要配合发射粒子函数中的起点，达成使用tex图中的某一部分。
                {u_size = , v_size = },表示对应方向帧大小（0-1）
                补充：如果切出来的图不对，检查下usize应该大于uv_offset_u，v_size要小于uv_offset_v
        mode:number，用于控制粒子与背景的混合方式，具体值为BLENDMODE =
                {
                    Disabled = 0,
                    AlphaBlended = 1,
                    Additive = 2,
                    Premultiplied = 3,
                    InverseAlpha = 4,
                    AlphaAdditive = 5,
                    VFXTest = 6,
                }
        
        --粒子数量与生命周期
        maxparticlenumber:必选，number，表示最大粒子数
        maxlifetime:number，粒子最大存活时间,生命周期/秒

        -- 颜色与缩放包络
        colour_envelope_name:string，必选，要和InitEnvelope中的COLOUR_ENVELOPE_NAME一致,代表使用对应的颜色变化曲线配置
        scale_envelope_name:sting,必选，要和InitEnvelope中的SCALE_ENVELOPE_NAME一致,代表使用对应的大小变化曲线配置

        --旋转与物理
        rotation:bool，为指定发射器启用或禁用旋转能力
        ground:bool,控制粒子是否与地面发生碰撞
        acceleration:表，设置粒子的三轴加速度,控制粒子的运动轨迹,格式如下：
                {
                    x=0,  x轴加速度
                    y = 0, y轴加速度（即重力加速）
                    z = 0，z轴加速度
                }
        dragcoefficient:number,设置阻力系数，控制粒子的空气阻力，取值范围为0-1

        --渲染顺序与深度
        order:number,设置渲染排序,控制粒子层的渲染顺序，数值越大越优先显示,一般为-3~3
        offset:number, 排序偏移值,即当order相同时，根据该属性排序，一般为-7~7
        depthtest:bool,是否启用深度测试,控制粒子的深度遮挡

        --特效增强
        bloom:bool,是否启用辉光,为粒子添加发光效果
        radius:number,发射半径,控制粒子发射的区域范围

        --实体关联
        killonentitydeath:bool,是否在实体死亡时销毁,控制粒子是否跟随实体生命周期
        follow:bool,是否跟随发射器移动,控制粒子是否跟随发射器移动

        --发射更新相关,必须要写！！！
        emitterlifetime:number或nil，粒子发生器的生命周期，单位秒，nil表示无限
        updatafn:函数，每帧调用的更新函数，注意该函数为工厂函数，接受原AddEmitter中的inst, effect, i，最后需要返回一个不带参数的的实际函数。比如：
            updatafn = function(inst, effect, emitter_index)
                return function()
                    --这里写发射粒子的代码
                end
            end
        一些提示：
            1.函数中绝大部分情况下是发射粒子，也就是发射器每帧发射粒子
            2.发射粒子的四个函数：
                    AddParticle:
                        effect:AddParticle         --最简单的粒子发射,发射的粒子不旋转，使用纹理的完整区域
                            (
                                emitter_id,        -- 发射器ID (0, 1, 2...)
                                lifetime,          -- 粒子生命周期(秒)
                                px, py, pz,        -- 初始位置
                                vx, vy, vz         -- 初始速度
                            )
                    AddParticleUV：
                        effect:AddParticleUV：     --发射带UV偏移的粒子，粒子不旋转。什么是UV？UV3D图形学中的标准术语，类似于纹理图集的水平和垂直方向，取值范围为0-1，通过uv可以让粒子使用同一张纹理图集的不同部分
                        (
                                emitter_id,        -- 发射器ID
                                lifetime,          -- 生命周期
                                px, py, pz,        -- 位置
                                vx, vy, vz,        -- 速度
                                uv_offset_u,       -- UV偏移U (横向)
                                uv_offset_v        -- UV偏移V (纵向)
                            )

                    AddRotatingParticle：
                        effect:AddRotatingParticle --发射使用纹理的完整区域的旋转粒子
                            (
                                emitter_id,        -- 发射器ID
                                lifetime,          -- 生命周期
                                px, py, pz,        -- 位置
                                vx, vy, vz,        -- 速度
                                angle,             -- 初始角度(度)
                                angular_velocity   -- 角速度(度/秒)
                            )
                    AddRotatingParticleUV：
                            effect:AddRotatingParticleUV --发射可以使用纹理指定部分的旋转粒子
                            (
                                emitter_id,        -- 发射器ID
                                lifetime,          -- 生命周期
                                px, py, pz,        -- 位置
                                vx, vy, vz,        -- 速度
                                angle,             -- 初始角度
                                angular_velocity,  -- 角速度
                                uv_offset_u,       -- UV偏移U
                                uv_offset_v        -- UV偏移V
                            )
            3.最后附带一个官方例子:
                    local function update_fn()
                        while inst.num_particles_to_emit > 1 do
                                    local vx, vy, vz = 0, 0, 0
                                    local lifetime = MIN_LIFETIME + (MAX_LIFETIME - MIN_LIFETIME) * UnitRand()
                                    local px, py, pz = emitter_shape()

                                    if use_uv_offset then
                                        local angle = math.random() * 360    
                                        local uv_offset = math.random(0, 7) * .125
                                        local ang_vel = UnitRand() * 4.0
                                        effect:AddRotatingParticleUV(
                                            0,
                                            lifetime,           -- lifetime
                                            px, py, pz,         -- position
                                            vx, vy, vz,         -- velocity
                                            angle, ang_vel,     -- angle, angular_velocity
                                            uv_offset, 0        -- uv offset
                                        )
                                    else
                                        effect:AddParticle(
                                            0,
                                            lifetime,           -- lifetime
                                            px, py, pz,         -- position
                                            vx, vy, vz          -- velocity
                                        )
                                    end
                                end
                            inst.num_particles_to_emit = inst.num_particles_to_emit - 1
                        end
                        inst.num_particles_to_emit = inst.num_particles_to_emit + inst.particles_per_tick * particle_mult
                    end
    }
]]